//NOTE: Check if the order of necessary operations and state modificaton in every
//		action is correct --WKCHEN 4/17/03'

//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//	MlmeModule.c
//		MLME module
//	history -- 01/14/03' created 
//
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
#include "os_common.h"

//=================== Subroutine of MLME Module
void vMlmeProc_AuthConfirmSME(PWB32_ADAPTER Adapter, UCHAR bResult);
void vMlmeProc_AuthIndicateSME(PWB32_ADAPTER Adapter);
void vMlmeTimerStart(PWB32_ADAPTER Adapter, USHORT wIdx, UINT timeout_value);
void vMlmeTimerStop(PWB32_ADAPTER Adapter, USHORT wIdx);
void vMlmeTimerHandler_1a(IN PVOID	Data);
void vMlmeTimerHandler(IN PVOID, IN PWB_BSSDESCRIPTION, IN PVOID, IN PVOID);
void vChkFatalErr(PWB32_ADAPTER Adapter);

//=================== Action Function of MLME/ESS Module
void vMlmeProc_EssAuthReq(PWB32_ADAPTER Adapter, pK_MSG psMlmeMsg);
void vMlmeProc_EssRxAuthFrame(PWB32_ADAPTER Adapter, pK_MSG psMlmeMsg);
void vMlmeProc_AuthCallback(PWB32_ADAPTER Adapter, pK_MSG psMlmeMsg);
void vMlmeProc_AssocCallback(PWB32_ADAPTER Adapter, pK_MSG psMlmeMsg);
void vMlmeProc_EssRxAuthWEP(PWB32_ADAPTER Adapter, pK_MSG psMlmeMsg);
void vMlmeProc_SendDeAuthReq(PWB32_ADAPTER Adapter, pK_MSG psMlmeMsg);
void vMlmeProc_RcvDeAuth(PWB32_ADAPTER Adapter, pK_MSG psMlmeMsg);
void vMlmeProc_SendAssocReq(PWB32_ADAPTER Adapter, pK_MSG psMlmeMsg);
void vMlmeProc_SendReAssocReq(PWB32_ADAPTER Adapter, pK_MSG psMlmeMsg);
void vMlmeProc_RcvAssocRsp(PWB32_ADAPTER Adapter, pK_MSG psMlmeMsg);
void vMlmeProc_RcvReAssocRsp(PWB32_ADAPTER Adapter, pK_MSG psMlmeMsg);
void vMlmeProc_SendDisAssocReq(PWB32_ADAPTER Adapter, pK_MSG psMlmeMsg);
void vMlmeProc_RcvDisAssoc(PWB32_ADAPTER Adapter, pK_MSG psMlmeMsg);
void vMlmeProc_AssocFailTimeout(PWB32_ADAPTER Adapter, pK_MSG psMlmeMsg);
void vMlmeProc_AuthFailTimeout(PWB32_ADAPTER Adapter, pK_MSG psMlmeMsg);

//=================== Action Function of MLME/IBSS Module
void vMlmeProc_IbssAuthReq(PWB32_ADAPTER Adapter, pK_MSG psMlmeMsg);
void vMlmeProc_IbssRxAuthFrame(PWB32_ADAPTER Adapter, pK_MSG psMlmeMsg);
void vMlmeProc_IbssRxAuthChallenge(PWB32_ADAPTER Adapter, pK_MSG psMlmeMsg);
void vMlmeProc_IbssRxAuthWEP(PWB32_ADAPTER Adapter, pK_MSG psMlmeMsg);
void vMlmeProc_IbssRxAuthResult(PWB32_ADAPTER Adapter, pK_MSG psMlmeMsg);
void vMlmeProc_IbssAuthChallengeCallback(PWB32_ADAPTER Adapter, pK_MSG psMlmeMsg);
void vMlmeProc_IbssAuthTxComplete(PWB32_ADAPTER Adapter, pK_MSG psMlmeMsg);
void vMlmeProc_IbssAuthFailTimeout(PWB32_ADAPTER Adapter, pK_MSG psMlmeMsg);
void vMlmeProc_IbssDeAuthReq(PWB32_ADAPTER Adapter, pK_MSG psMlmeMsg);

//========== Define the state machine table of MLME module =================
static const K_TRANS asInActive[] =
{
    // Call MLME_FindSTA()
	{K_NULL_MSG,						vProc_Null							}
};

static const K_TRANS asIBSS_Join_Sync[] =
{
	{K_NULL_MSG,						vProc_Null							}
};

//=============== ESS Process State Machine ==============================
static const K_TRANS asState_1[] =
{
	{MLMEMSG_AUTH_REQ,					vMlmeProc_EssAuthReq				},
	{MLMEMSG_DEAUTH_REQ,				vMlmeProc_SendDeAuthReq				},
	{K_NULL_MSG,						vProc_Null							}
};

static const K_TRANS asAuth_Req[] =
{
	{MLMEMSG_RCV_AUTH,					vMlmeProc_EssRxAuthFrame			},
	{MLMEMSG_DEAUTH_REQ,				vMlmeProc_SendDeAuthReq				},
	{MLMEMSG_AUTH_CALLBACK,				vMlmeProc_AuthCallback				},
	{MLMEMSG_TIMEOUT,					vMlmeProc_AuthFailTimeout			},
	{K_NULL_MSG,						vProc_Null							}
};

static const K_TRANS asAuth_WEP[] =
{
	{MLMEMSG_RCV_AUTH,					vMlmeProc_EssRxAuthWEP				},
	{MLMEMSG_DEAUTH_REQ,				vMlmeProc_SendDeAuthReq				},
	{MLMEMSG_AUTH_CALLBACK,				vMlmeProc_AuthCallback				},
	{MLMEMSG_TIMEOUT,					vMlmeProc_AuthFailTimeout			},
	{K_NULL_MSG,						vProc_Null							}
};

static const K_TRANS asState_2[] =
{
	{MLMEMSG_ASSOC_REQ,					vMlmeProc_SendAssocReq				},
	{MLMEMSG_REASSOC_REQ,				vMlmeProc_SendReAssocReq			},
	{MLMEMSG_DEAUTH_REQ,				vMlmeProc_SendDeAuthReq				},
	{MLMEMSG_DISASSOC_REQ,				vMlmeProc_SendDeAuthReq				},
	{MLMEMSG_RCV_DEAUTH,				vMlmeProc_RcvDeAuth			        },
	{MLMEMSG_RCV_DISASSOC,				vMlmeProc_RcvDisAssoc			    },
	{K_NULL_MSG,						vProc_Null							}
};

static const K_TRANS asAssoc_Req[] =
{
	{MLMEMSG_DEAUTH_REQ,				vMlmeProc_SendDeAuthReq				},
	{MLMEMSG_DISASSOC_REQ,				vMlmeProc_SendDeAuthReq				},
	{MLMEMSG_RCV_ASSOCRSP,				vMlmeProc_RcvAssocRsp				},
	{MLMEMSG_RCV_REASSOCRSP,			vMlmeProc_RcvReAssocRsp				},
	{MLMEMSG_RCV_DISASSOC,				vMlmeProc_RcvDisAssoc				},
	{MLMEMSG_ASSOCREQ_CALLBACK,			vMlmeProc_AssocCallback				},
	{MLMEMSG_REASSOCREQ_CALLBACK,		vMlmeProc_AssocCallback				},
	{MLMEMSG_TIMEOUT,					vMlmeProc_AssocFailTimeout			},
	{K_NULL_MSG,						vProc_Null							}
};

static const K_TRANS asState_3[] =
{
	{MLMEMSG_DEAUTH_REQ,				vMlmeProc_SendDeAuthReq				},
	{MLMEMSG_DISASSOC_REQ,				vMlmeProc_SendDeAuthReq				},
	{MLMEMSG_RCV_DEAUTH,				vMlmeProc_RcvDeAuth		    		},
	{MLMEMSG_RCV_DISASSOC,				vMlmeProc_RcvDisAssoc		    	},
	{K_NULL_MSG,						vProc_Null							}
};

//============ (IBSS + DUT) Process State Machine ==============================
static const K_TRANS asIdle_Scan[] =
{
    // include open / share, handle success/fail case of RCV_AUTH
	{MLMEMSG_RCV_AUTH,					vMlmeProc_IbssRxAuthFrame			}, 
	
	// include open / share for DUT
	{MLMEMSG_AUTH_REQ,					vMlmeProc_IbssAuthReq				}, 
	
	// Disconnect request by SME (send deAuthenticate)
	{MLMEMSG_DEAUTH_REQ,				vMlmeProc_IbssDeAuthReq			},
	
	{K_NULL_MSG,						vProc_Null							}
};

static const K_TRANS asIBSS_Auth_Req[] =   
{
    // include open / share, handle success/fail case of RCV_AUTH
	{MLMEMSG_RCV_AUTH,					vMlmeProc_IbssRxAuthChallenge		},
	
	// Disconnect request by SME (send deAuthenticate)
	{MLMEMSG_DEAUTH_REQ,				vMlmeProc_IbssDeAuthReq			},
	
	{MLMEMSG_TIMEOUT,					vMlmeProc_IbssAuthFailTimeout		},
	{K_NULL_MSG,						vProc_Null							}
};

static const K_TRANS asIBSS_Auth_Chanlge[] =  
{
    // Rx Auth-Frame(3) + WEP (ChallengeText) and SW check ChangeText success, 
    // then Tx Auth-Frame (4), handle success/fail case of RCV_AUTH
	{MLMEMSG_RCV_AUTH,					vMlmeProc_IbssRxAuthWEP		        },
	
	// Tx Callback, copy HW ChallengeText into local MAC session memory
	{MLMEMSG_AUTH_CALLBACK,				vMlmeProc_IbssAuthChallengeCallback	},
	
	// Disconnect request by SME (send deAuthenticate)
	{MLMEMSG_DEAUTH_REQ,				vMlmeProc_IbssDeAuthReq			},
	
	{MLMEMSG_TIMEOUT,					vMlmeProc_IbssAuthFailTimeout		},
	{K_NULL_MSG,						vProc_Null							}
};

static const K_TRANS asIBSS_Auth_WEP[] =  
{
    // only include share key, handle success/fail case of RCV_AUTH
	{MLMEMSG_RCV_AUTH,					vMlmeProc_IbssRxAuthResult			},
	
	// Disconnect request by SME (send deAuthenticate)
	{MLMEMSG_DEAUTH_REQ,				vMlmeProc_IbssDeAuthReq			},
	
	{MLMEMSG_TIMEOUT,					vMlmeProc_IbssAuthFailTimeout		},
	{K_NULL_MSG,						vProc_Null							}
};

static const K_TRANS asIBSS_Auth_IND[] =  
{
    // include open / sharekey path, handle success/fail case of RCV_AUTH
	{MLMEMSG_AUTH_CALLBACK,				vMlmeProc_IbssAuthTxComplete		},

	// Disconnect request by SME (send deAuthenticate)
	{MLMEMSG_DEAUTH_REQ,				vMlmeProc_IbssDeAuthReq			},
	{K_NULL_MSG,						vProc_Null							}
};


static const K_TRANS asIBSS_State_2[] =   
{
	// Disconnect request by SME (send deAuthenticate)
	{MLMEMSG_DEAUTH_REQ,				vMlmeProc_IbssDeAuthReq			},
	{K_NULL_MSG,						vProc_Null							}
};


//========= MLME State Transition Table ==============================
static const K_TRANS* psMlmeTransTable[] =          
{                                                   
	//====== the state of MLME module               
    asInActive,                                     
	asIdle_Scan,                                  
	                                              
	//====== the state of MLME/ESS module           
	asState_1,                                      
	asAuth_Req,                                       
	asAuth_WEP,                                   
	asState_2,                                    
	asAssoc_Req,                                      
	asState_3,                                     

    //====== the state of MLME/ESS module           
    asIBSS_Join_Sync,                               
    asIBSS_Auth_Req,                          
	asIBSS_Auth_Chanlge,       
	asIBSS_Auth_WEP,                      
	asIBSS_Auth_IND,        
	asIBSS_State_2,             
};                         
                       
//=========================================================================
//      Subroutine of MLME Module 
//=========================================================================
void vMlmeProc_AuthConfirmSME(PWB32_ADAPTER Adapter, UCHAR bResult)
{
	K_MSG	sSmeMsg;

	//--- inform SME ----------
	sSmeMsg.wMsgType = SMEMSG_AUTHEN_CFM; 
	sSmeMsg.pMsgPtr = &bResult;
	SME_Entry(Adapter, &sSmeMsg);
}

void vMlmeProc_AuthIndicateSME(PWB32_ADAPTER Adapter)
{
	K_MSG	sSmeMsg;

	//--- inform SME ----------
	sSmeMsg.wMsgType = SMEMSG_AUTHEN_IND; 
	sSmeMsg.pMsgPtr = NULL;
	SME_Entry(Adapter, &sSmeMsg);
}

void vMlmeTimerStart(PWB32_ADAPTER Adapter, USHORT wIdx, UINT timeout_value)
{
	if (Adapter->sLocalPara.ShutDowned == FALSE)
	{
		if (timeout_value<MIN_TIMEOUT_VAL)
			timeout_value=MIN_TIMEOUT_VAL;
		///NdisMSetTimer(&Adapter->asBSSDescriptElement[(wIdx)].nTimer, timeout_value);
		OS_TIMER_SET(&Adapter->asBSSDescriptElement[(wIdx)].nTimer, timeout_value);
	}
}


void vMlmeTimerStop(PWB32_ADAPTER Adapter, USHORT wIdx)
{
//    BOOLEAN boValue; // NDIS defined type

    ///NdisMCancelTimer(&Adapter->asBSSDescriptElement[wIdx].nTimer, &boValue);
//	OS_TIMER_CANCEL(&Adapter->asBSSDescriptElement[wIdx].nTimer, &boValue);
//For cleaner compile
	OS_TIMER_CANCEL(&Adapter->asBSSDescriptElement[wIdx].nTimer, 0);
	#ifdef _PE_STATE_DUMP_
	WBDEBUG(("STATE: mlme cancel timer %x return valule =%x\n", wIdx, boValue));
	#endif
}

//for only one argument
void vMlmeTimerHandler_1a(IN PVOID	Data)
{
	vMlmeTimerHandler(NULL, (PWB_BSSDESCRIPTION)Data, NULL, NULL);
}

void vMlmeTimerHandler(IN PVOID			SystemSpecific1,
						IN PWB_BSSDESCRIPTION psBSS,
						IN PVOID			SystemSpecific2,
						IN PVOID			SystemSpecific3)
{
	K_MSG sTimerMsg;
	#ifdef _IBSS_BEACON_SEQ_STICK_
	PWB32_ADAPTER Adapter = psBSS->psAdapter;

	if (psBSS->wIndex == 1)
	{
		//WBDEBUG(("! send broadcast null frame.\n"));
		SendBCNullData(Adapter, psSME->wDesiredJoinBSS);
	}
	else
	#endif
	{
		psBSS->boInTimerHandler = TRUE;
    	sTimerMsg.wMsgType = MLMEMSG_TIMEOUT;
		sTimerMsg.wInstance = psBSS->wIndex;
		sTimerMsg.pMsgPtr = NULL;
		MLME_Entry(psBSS->psAdapter, &sTimerMsg);
		psBSS->boInTimerHandler = FALSE;
	}
}

// NB: Transmit Frame timeout, but TxMMPDU didn't release. ie. no Tx Callback happened
void vChkFatalErr(PWB32_ADAPTER    Adapter)
{
	#ifdef _PE_TX_DUMP_
	int i;
	//ULONG dwIntStatus;

	for (i = 0; i < MAX_NUM_TX_MMPDU; i++)
    {
		if (Adapter->sMlmeFrame.TxMMPDUInUse[i]==TRUE)
    	{
			WBDEBUG(("FATAL: MLME Timeout, but no TxCallback\n"));
			//TODO: without any corresponding HAL function
			//WBDEBUG(("IntS:%x\n",(uint)dwIntStatus));
        	//_asm{int 3}
		}
	}
	#endif
}

void MLME_initState(PWB_BSSDESCRIPTION psBSS)
{
	psBSS->wState=INACTIVE;
}

void MLME_IBSSinitState(PWB32_ADAPTER Adapter)
{
	int i;

	for (i=1;i<MAX_BSS_DESCRIPT_ELEMENT;i++)
	{
		if (psBSS(i)->bBssType == IBSS_NET)
		{
			psBSS(i)->wState = INACTIVE;
		}
	}
}

void MLME_findSTA(PWB_BSSDESCRIPTION psBSS)
{
	psBSS->wState=IDLE_SCAN;
}

void MLME_JoinCfm(PWB_BSSDESCRIPTION psBSS, UCHAR BssType)
{
	if (BssType == IBSS_NET)
		psBSS->wState = IBSS_JOIN_SYNC;
	else
		psBSS->wState = STATE_1;
}

BOOL MLME_Init(PWB32_ADAPTER Adapter)
{
	USHORT i;

	OS_SPIN_LOCK_ALLOCATE( &Adapter->sMlmeFrame.MLMESpinLock );

	//MLME related variable initialization
	MLMEResetTxRx(Adapter);
	// Initialze the MLME-internal state
	if( OS_MEMORY_ALLOC_OK != OS_MEMORY_ALLOC( (PVOID *)&Adapter->asBSSDescriptElement,
												sizeof(WB_BSSDESCRIPTION) * MAX_BSS_DESCRIPT_ELEMENT ) )
	{
		#ifdef _PE_STATE_DUMP_
		WBDEBUG(("[w35und] MLME_Init allocate memory %d fail ->\n", sizeof(WB_BSSDESCRIPTION) * MAX_BSS_DESCRIPT_ELEMENT ));
		#endif
		Adapter->asBSSDescriptElement = NULL;
		return FALSE;
	}
	OS_MEMORY_CLEAR( Adapter->asBSSDescriptElement, sizeof(WB_BSSDESCRIPTION) * MAX_BSS_DESCRIPT_ELEMENT );
	#ifdef _PE_STATE_DUMP_
	WBDEBUG(("[w35und] vBSSdescriptionInit allocate memory %d\n", sizeof(WB_BSSDESCRIPTION) * MAX_BSS_DESCRIPT_ELEMENT ));
	#endif

	vBSSdescriptionInit(Adapter);
	for (i=0; i<MAX_BSS_DESCRIPT_ELEMENT; i++)
	{
		///NdisMInitializeTimer(&(psBSS(i)->nTimer),
		///					  //Adapter->sNdis.MiniportAdapterHandle,
		///					  Adapter->WbNdis.MiniportAdapterHandle,
		///					  (PVOID) vMlmeTimerHandler,
		///					  (PVOID) psBSS(i));
		OS_TIMER_INITIAL(&(psBSS(i)->nTimer),
							  //Adapter->WbNdis.MiniportAdapterHandle,
							  (PVOID) vMlmeTimerHandler,
							  (PVOID) psBSS(i));
	}

	return TRUE;
}

//=============================================================================
// Function:
//   MLMEHalt()
//
// Description:
//   Stop the MLME and reclaim the resources during the
//   initialization.
//
//=============================================================================
void MLME_Halt(IN PWB32_ADAPTER Adapter)
{
    USHORT     i;

	for (i=MAX_BSS_DESCRIPT_ELEMENT-1; i>0; i--)
	{
		vMlmeTimerStop(Adapter, i);
	}
	for (i=MAX_BSS_DESCRIPT_ELEMENT-1; i>0; i--)
	{
		while (psBSS(i)->boInTimerHandler == TRUE)
		{
			///NdisMSleep(10000);//10ms
			OS_SLEEP( 10000 );
		}
	}

	if( Adapter->asBSSDescriptElement )
	{
		OS_MEMORY_FREE( Adapter->asBSSDescriptElement, sizeof(WB_BSSDESCRIPTION) * MAX_BSS_DESCRIPT_ELEMENT );
		Adapter->asBSSDescriptElement = NULL;	//[WK 20060626]
	}
	#ifdef _PE_STATE_DUMP_
	WBDEBUG(("STATE: Mlme halt.\n"));
	#endif

	OS_SPIN_LOCK_FREE( &Adapter->sMlmeFrame.MLMESpinLock );
}

void MLME_Stop(IN PWB32_ADAPTER Adapter)
{
    USHORT     i;

	for (i=MAX_BSS_DESCRIPT_ELEMENT-1; i>0; i--)
	{
		vMlmeTimerStop(Adapter, i);
	}
}

void MLME_Entry(PWB32_ADAPTER Adapter, pK_MSG psMlmeMsg)
{
	USHORT	i;
	struct Management_Frame		*psMlmeFrame;
	psMLME_TXCALLBACK psTxCallback;

	if (psMlmeMsg->wMsgType==KNLMSG_RESET)
	{
		//reset state and timer ?? which descript ??
		return;
	}
    //search index from the BSSdescriptSet or get from the incoming msg
	// SMEMSG : 0x00 ~ 0x1F
	// RX_ISR : 0x20 ~ 0x3F
	// TX_ISR : 0x40 ~ 0x4F
	// MLME Timeout
	if (psMlmeMsg->wMsgType>=0x50)
	{
	}
	else if (psMlmeMsg->wMsgType>=0x40)
	{	// TX_ISR
		psTxCallback = psMlmeMsg->pMsgPtr;
		psMlmeFrame = (struct Management_Frame *)psTxCallback->psFramePtr;
		//WBDEBUG(("tx callback:\n"));
		//DataDmp(psMlmeFrame->DA, 6, 0);
		if ((i=wBSSfindMACaddr(Adapter, psMlmeFrame->DA))==0)
		{	// not find SA, may be new Entry
			// ???? to be define action
			return;
		}
		psMlmeMsg->wInstance = i;
		psMlmeMsg->wMsgType = (0x40|((psMlmeFrame->frame_control.mac_frame_info & 0xf0)>>4))+1;
	} 
	else if (psMlmeMsg->wMsgType>=0x20)
	{	// RX_ISR
		psMlmeFrame = (struct Management_Frame *)(((psRXDATA)psMlmeMsg->pMsgPtr)->pbFramePtr);
		//if ((i=wBSSfindMACaddr(Adapter, psMlmeFrame->SA))==0)
		if (psBSS(psMlmeMsg->wInstance)->wState < IDLE_SCAN)
		{	// not find SA, may be new Entry. 
			// Consider case: in IBSS receive Authen-Req-frame, may need to create BSS Entry
			// ???? to be define action
			return;
		}
		//psMlmeMsg->wInstance = i;
		// dispatch authentication, deauthentication, association, reassociation, 
		// and disassociation according to the subtype of incoming frame to redefine
		// the wMsgType
		psMlmeMsg->wMsgType = (0x20|((psMlmeFrame->frame_control.mac_frame_info & 0xf0)>>4))+1 ;  // NOTE: MSG coding must match (FrameSubtype+1)
	} 
	else
	{	//Other SME messages are from SME, wInstance is assigned by SME task. eg. Authen_Req, Assoc_Req
		// don't remap wMsgType code
	}
	#ifdef _PE_STATE_DUMP_
	WBDEBUG(("STATE: iMLME i= %x, s=%x, m=%x\n", psMlmeMsg->wInstance,
							psBSS(psMlmeMsg->wInstance)->wState,
							psMlmeMsg->wMsgType));
	#endif
	vKNL_StateMachine(Adapter, psMlmeTransTable, 
						psBSS(psMlmeMsg->wInstance)->wState, psMlmeMsg);
	#ifdef _PE_STATE_DUMP_
	WBDEBUG(("STATE: oMLME i= %x, s=%x\n", psMlmeMsg->wInstance,
							psBSS(psMlmeMsg->wInstance)->wState));
	#endif
}

//======================================================================================
//      Action Function of MLME / ESS State Transition Table 
//======================================================================================
void vMlmeProc_EssAuthReq(PWB32_ADAPTER Adapter, pK_MSG psMlmeMsg)
{
	USHORT	i;

	i = psMlmeMsg->wInstance;
	psBSS(i)->wAuthSeqNum = 1;

	SendAuthenticationRequest(Adapter, i , psSME->bDesiredAuthMode, 1,	MLME_SUCCESS, NULL);
    //--- wait for response
    vMlmeTimerStart(Adapter, i, AUTH_FAIL_TIMEOUT);
    //--- change to next state
    psBSS(i)->wState = AUTH_REQ;
}

void vMlmeProc_EssRxAuthFrame(PWB32_ADAPTER Adapter, pK_MSG psMlmeMsg)
{
	K_MSG	sSmeMsg;
	struct	Authentication_Frame_Body	*psAuthFB;
	UCHAR	*psChallengeTxt;
	UCHAR	bResult;
	USHORT	i;
	USHORT	SeqNo, StatusCode; //20060926 add by anson's endian

	#ifdef _PE_STATE_DUMP_
	WBDEBUG(("RX: receive auth response\n"));
	#endif
	i = psMlmeMsg->wInstance;
	vMlmeTimerStop(Adapter,i); // stop timer, no matter success or fail.
	psAuthFB = (struct Authentication_Frame_Body *)
					(((psRXDATA)psMlmeMsg->pMsgPtr)->pbFramePtr + sizeof(struct Management_Frame));
	psChallengeTxt = (UCHAR *)(psAuthFB) + sizeof(struct Authentication_Frame_Body);
        //---20060926 add by anson's endian
        SeqNo = cpu_to_le16( psAuthFB->sequenceNumber );
        StatusCode = cpu_to_le16( psAuthFB->statusCode );
        //---end 20060926 add by anson's endian
        
	//if  ((psAuthFB->sequenceNumber != 2)|| (psAuthFB->statusCode != MLME_SUCCESS)) //20060926 anson's endian
	if  ((SeqNo != 2)|| (StatusCode != MLME_SUCCESS)) 
	{	// auth-fail
		// free RX frame buffer => It will be free at MLMERcvFrame() -- WKCHEN
		sSmeMsg.wMsgType = SMEMSG_AUTHEN_CFM;
		// WKCHEN_NOTE2 : auto update SME->DesiredAuthMode
		//if (psAuthFB->statusCode == 13) //20060926 anson's endian
		if ((StatusCode == 13) 
             && (psSME->bDesiredAuthMode != WPA_AUTH)&&(psSME->bDesiredAuthMode != WPAPSK_AUTH)
             #ifdef _WPA2_
			 &&(psSME->bDesiredAuthMode != WPA2PSK_AUTH)&&(psSME->bDesiredAuthMode != WPA2_AUTH)
			 #endif //end def _WPA2_
			 )
			
		{
			if (psSME->bDesiredAuthMode==SHARE_AUTH)
			{
				psSME->bDesiredAuthMode = OPEN_AUTH;
			}
			else
			{
				psSME->bDesiredAuthMode = SHARE_AUTH;
			}
			psBSS(i)->wState = STATE_1;
			bResult = RETRY;
		}
		else
		{
			psBSS(i)->wState = IDLE_SCAN;
			bResult = GIVE_UP;
		}
		// NOTE: psBSS(i)->wState must change state before call SME_Entry(), 
		//       SME_Entry() will call MLME_Entry()
		sSmeMsg.pMsgPtr = &bResult;
		SME_Entry(Adapter, &sSmeMsg);
		// NOTE: after SME_Entry() return, psBSS(i)->wState is AUTH_REQ, not STATE_1
		return;
	}
	// Authen Success
	psBSS(i)->wAuthAlgo = cpu_to_le16( psAuthFB->algorithmNumber ); //20060926 anson's endian
	if (psBSS(i)->wAuthAlgo==OPEN_AUTH)
	{	// OPEN Authen Confirm
		psBSS(i)->wState = STATE_2;
		sSmeMsg.wMsgType = SMEMSG_AUTHEN_CFM;
		bResult = MLME_SUCCESS;
		sSmeMsg.pMsgPtr = &bResult;
		SME_Entry(Adapter, &sSmeMsg);
	} 
	else
	{	// SHARE_AUTH
		// Must restart AutheFailTimer
		vMlmeTimerStart(Adapter, i, AUTH_FAIL_TIMEOUT);
		SendAuthenticationRequest(Adapter,
							//i, psAuthFB->algorithmNumber,   //20060926 anson's endian
							//++psAuthFB->sequenceNumber,MLME_SUCCESS,
							i, psBSS(i)->wAuthAlgo,
							SeqNo+1,MLME_SUCCESS,
							(PUCHAR)psChallengeTxt);
		psBSS(i)->wState = AUTH_WEP;
	}
}

void vMlmeProc_AuthCallback(PWB32_ADAPTER Adapter, pK_MSG psMlmeMsg)
{
	K_MSG	sSmeMsg;
	USHORT	i;
	UCHAR	bResult;

	if (((MLME_TXCALLBACK*)psMlmeMsg->pMsgPtr)->bResult == TRANSMIT_FRAME_FAIL)
	{
		i = psMlmeMsg->wInstance;
		psBSS(i)->wState= IDLE_SCAN;
		sSmeMsg.wMsgType=SMEMSG_AUTHEN_CFM;
		bResult=GIVE_UP;
		sSmeMsg.pMsgPtr=&bResult;
		SME_Entry(Adapter, &sSmeMsg);
	}
}

void vMlmeProc_AssocCallback(PWB32_ADAPTER Adapter, pK_MSG psMlmeMsg)
{
	K_MSG	sSmeMsg;
	UCHAR	bResult;
	USHORT i;

	if (((MLME_TXCALLBACK*)psMlmeMsg->pMsgPtr)->bResult == TRANSMIT_FRAME_FAIL)
	{
		i = psMlmeMsg->wInstance;
		psBSS(i)->wState= IDLE_SCAN;
		sSmeMsg.wMsgType=SMEMSG_ASSOC_CFM;
		bResult=GIVE_UP;
		sSmeMsg.pMsgPtr=&bResult;
		SME_Entry(Adapter, &sSmeMsg);
		// NOTE: if we design Retry_Assoc, 
		// then next MLMEstate is STATE_2, SMEstate is AUTHENTICATED
	}
}

void vMlmeProc_EssRxAuthWEP(PWB32_ADAPTER Adapter, pK_MSG psMlmeMsg)
{
	K_MSG sSmeMsg;
	struct  Authentication_Frame_Body *psAuthFB;
	USHORT	i;
	UCHAR	bResult;

	i = psMlmeMsg->wInstance;
	vMlmeTimerStop(Adapter, i);
	psAuthFB = (struct Authentication_Frame_Body *)
					(((psRXDATA)psMlmeMsg->pMsgPtr)->pbFramePtr + sizeof(struct Management_Frame));
	if  ((cpu_to_le16( psAuthFB->sequenceNumber ) != 4)||( cpu_to_le16( psAuthFB->statusCode ) != MLME_SUCCESS)) //20060926 anson's endian
	{
		psBSS(i)->wState = IDLE_SCAN;
		sSmeMsg.wMsgType = SMEMSG_AUTHEN_CFM;
		bResult = GIVE_UP; 
		sSmeMsg.pMsgPtr = &bResult;
		SME_Entry(Adapter, &sSmeMsg);
		return;
	}
	// Authen Success
	psBSS(i)->wState = STATE_2;
	sSmeMsg.wMsgType = SMEMSG_AUTHEN_CFM;
	bResult = MLME_SUCCESS;
	sSmeMsg.pMsgPtr = &bResult;
	SME_Entry(Adapter, &sSmeMsg);
}

// This function used only for ESS AuthenFail
void vMlmeProc_AuthFailTimeout(PWB32_ADAPTER Adapter, pK_MSG psMlmeMsg)
{
	K_MSG	sSmeMsg;
	USHORT	i;
	UCHAR	bResult;

	//vChkFatalErr(Adapter);

	i = psMlmeMsg->wInstance;

	if (psBSS(i)->wState<STATE_2)
	{
		sSmeMsg.wMsgType=SMEMSG_AUTHEN_CFM;
		// NOTE: following procedure are being verified, not meet all cases, welcome comments
		if (psSME->bDesiredAuthMode==SHARE_AUTH)
		{
			psSME->bDesiredAuthMode = OPEN_AUTH;
			bResult=RETRY;
			psBSS(i)->wState= STATE_1;
		} else
		{
			USHORT	EventValue;

			// OPEN-AUTH timeout fail, just GIVE_UP
			bResult=GIVE_UP;
			psBSS(i)->wState= IDLE_SCAN;

			EventValue = EVENT_AUTH_FAIL | EVENT_REASON_TIMEOUT;
			FillEventLog(Adapter, EventValue);
		}
		sSmeMsg.pMsgPtr=&bResult;
		SME_Entry(Adapter, &sSmeMsg);
	}
}

void vMlmeProc_SendDeAuthReq(PWB32_ADAPTER Adapter, pK_MSG psMlmeMsg)
{
	USHORT	i, wReason;

	i = psMlmeMsg->wInstance;
	if (psBSS(i)->wState<STATE_2)
	{	// just back to IDLE_SCAN, do nothing
		psBSS(i)->wState=IDLE_SCAN;
		return; 
	}
	// State after STATE_2, should send out Deauthen-frame, then back to IDLE_SCAN
	psBSS(i)->wState = IDLE_SCAN;
	wReason = *(USHORT *)psMlmeMsg->pMsgPtr;
	SendDeauthentication(Adapter, i, wReason);
}

void vMlmeProc_SendAssocReq(PWB32_ADAPTER Adapter, pK_MSG psMlmeMsg)
{
	USHORT	i;
	psMLME_ASSOCREQ_PARA pAssocReqPara;
	BOOL Reasso=0;

	// from SME, need supply the capability information, listen interval, current AP address,
	// SSID, supported rates
	i = psMlmeMsg->wInstance;
	pAssocReqPara = psMlmeMsg->pMsgPtr;
	psBSS(i)->wState = ASSOC_REQ;
	// NOTE: didn't pass pAssocReqPara
	SendAssociationRequest(Adapter, i ,Reasso);//Reasso flag for distinguish reassociation and association frame
	vMlmeTimerStart(Adapter, i, ASSOC_FAIL_TIMEOUT);
}

void vMlmeProc_SendReAssocReq(PWB32_ADAPTER Adapter, pK_MSG psMlmeMsg)
{
	USHORT	i;
	psMLME_REASSOCREQ_PARA pReAssocReqPara;
	BOOL Reasso=0;

	i = psMlmeMsg->wInstance;
	pReAssocReqPara = psMlmeMsg->pMsgPtr;
	psBSS(i)->wState = ASSOC_REQ;
	// NOTE: didn't pass ReAssocReqPara
	Reasso=1;
	SendAssociationRequest(Adapter, i, Reasso);//modify SendReassociationRequest to SendAssociationRequest
	vMlmeTimerStart(Adapter, i, REASSOC_FAIL_TIMEOUT);
}

void vMlmeProc_AssocFailTimeout(PWB32_ADAPTER Adapter, pK_MSG psMlmeMsg)
{
	K_MSG	sSmeMsg;
	USHORT	i;
	UCHAR	bResult;
	USHORT	EventValue;

	//vChkFatalErr(Adapter);
	EventValue = EVENT_ASSOC_FAIL | EVENT_REASON_TIMEOUT;
	FillEventLog(Adapter, EventValue);

	i = psMlmeMsg->wInstance;
	psBSS(i)->wState = IDLE_SCAN; //??
	sSmeMsg.wMsgType = SMEMSG_ASSOC_CFM;
	bResult = GIVE_UP;  //TIMEOUT;
	sSmeMsg.pMsgPtr = &bResult;
	SME_Entry(Adapter, &sSmeMsg);
}

void vMlmeProc_RcvAssocRsp(PWB32_ADAPTER Adapter, pK_MSG psMlmeMsg)
{
	K_MSG	sSmeMsg;
	USHORT	i;
	struct  Association_Response_Frame_Body* psAssocFB;
	UCHAR	bResult;
//	ULONG   dwData;
	USHORT	StatusCode; //20060926 add by anson's endian

	i = psMlmeMsg->wInstance;
	vMlmeTimerStop(Adapter, i);
	psAssocFB = (struct Association_Response_Frame_Body *)
					(((psRXDATA)psMlmeMsg->pMsgPtr)->pbFramePtr + sizeof(struct Management_Frame));
	StatusCode = cpu_to_le16(psAssocFB->statusCode); //20060926 add by anson's endian

	//if (psAssocFB->statusCode == 0) // STATUS_SUCCESS  //20060926 anson's endian
	if (StatusCode == 0) // STATUS_SUCCESS
	{
		Adapter->sLocalPara.Association_ID = cpu_to_le16( psAssocFB->Association_ID ); //20060926 anson's endian
		hal_set_listen_interval(&Adapter->sHwData, psLOCAL->ListenInterval);
		hal_set_aid(&Adapter->sHwData, psLOCAL->Association_ID);
		psBSS(i)->wState = STATE_3;
		bResult = MLME_SUCCESS;
		//#ifdef _WPA_
		psSME->AssocRespVarLen = ((psRXDATA)psMlmeMsg->pMsgPtr)->FrameLength - 
									sizeof(struct Management_Frame) - 6;
		OS_MEMORY_COPY(&(psSME->AssocRespCapability), &(psAssocFB->capability_information), 2);
		OS_MEMORY_COPY(&(psSME->AssocRespStatus), &(psAssocFB->statusCode), 2);
		// fixed field length = 6
		OS_MEMORY_COPY( psSME->AssocRespVarIE, &psAssocFB->supportedRates, psSME->AssocRespVarLen );
		#ifdef _PE_TX_DUMP_
		WBDEBUG(("Assoc resp Var IE:\n"));
		DataDmp(psSME->AssocRespVarIE, psSME->AssocRespVarLen,0);
		#endif
		//#endif
	}
	else
	{
		USHORT	EventValue;

		// which state it will return ?? back to IDLE_SCAN
		psBSS(i)->wState = IDLE_SCAN;
		bResult = GIVE_UP; // ?? reason code ??
		#ifdef _PE_STATE_DUMP_
		WBDEBUG(("***** Assoc confirm *****    status=%d\n", psAssocFB->statusCode));
		#endif

		//suppose the value of reason will not excess 256
		//EventValue = EVENT_ASSOC_FAIL | (UCHAR )psAssocFB->statusCode; //20060926 anson's endian
                EventValue = EVENT_ASSOC_FAIL | (StatusCode&0xff);
		FillEventLog(Adapter, 0x30 );//EventValue);
	}
	sSmeMsg.wMsgType = SMEMSG_ASSOC_CFM;
	sSmeMsg.pMsgPtr = &bResult;
	SME_Entry(Adapter, &sSmeMsg);
}

void vMlmeProc_RcvReAssocRsp(PWB32_ADAPTER Adapter, pK_MSG psMlmeMsg)
{
	K_MSG sSmeMsg;
	USHORT	i;
	struct  Association_Response_Frame_Body* psAssocFB;
	UCHAR	bResult;
	USHORT	StatusCode;  //20060926 add by anson's endian

	i = psMlmeMsg->wInstance;
	vMlmeTimerStop(Adapter, i);
	psAssocFB = (struct Association_Response_Frame_Body *)
					(((psRXDATA)psMlmeMsg->pMsgPtr)->pbFramePtr + sizeof(struct Management_Frame));
        StatusCode = cpu_to_le16(psAssocFB->statusCode); //20060926 anson's endian
	//if (psAssocFB->statusCode == 0) // STATUS_SUCCESS  
        if (StatusCode == 0) // STATUS_SUCCESS
	{
		//reset previous BSSdescription 
		psBSS(i)->wState = STATE_3;
		bResult = MLME_SUCCESS;
		//#ifdef _WPA_
		psSME->AssocRespVarLen = ((psRXDATA)psMlmeMsg->pMsgPtr)->FrameLength - 
									sizeof(struct Management_Frame) - 6;
		// fixed field length = 6
		OS_MEMORY_COPY( &(psSME->AssocRespCapability), &(psAssocFB->capability_information), 2);
		OS_MEMORY_COPY( &(psSME->AssocRespStatus), &(psAssocFB->statusCode), 2);
		OS_MEMORY_COPY( psSME->AssocRespVarIE, &psAssocFB->supportedRates, psSME->AssocRespVarLen );
		#ifdef _PE_TX_DUMP_
		WBDEBUG(("Assoc resp Var IE:\n"));
		DataDmp(psSME->AssocRespVarIE, psSME->AssocRespVarLen,0);
		#endif
		//#endif
	}
	else
	{
		USHORT	EventValue;

		// which state it will return ?? back to IDLE_SCAN
		psBSS(i)->wState = IDLE_SCAN;
		bResult = GIVE_UP; // ?? reason code ??	

		//suppose the value of reason will not excess 256
		//EventValue = EVENT_ASSOC_FAIL | (UCHAR)psAssocFB->statusCode; //20060926 anson's endian
                EventValue = EVENT_ASSOC_FAIL | (StatusCode&0xff);
		FillEventLog(Adapter, EventValue);
	}
	sSmeMsg.wMsgType = SMEMSG_ASSOC_CFM;
	sSmeMsg.pMsgPtr = &bResult;
	SME_Entry(Adapter, &sSmeMsg);
}

void vMlmeProc_RcvDeAuth(PWB32_ADAPTER Adapter, pK_MSG psMlmeMsg)
{
	K_MSG	sSmeMsg;
	USHORT		i,wReason;

	i = psMlmeMsg->wInstance;

	OS_MEMORY_COPY( &wReason, ((psRXDATA)psMlmeMsg->pMsgPtr)->pbFramePtr + sizeof(struct Management_Frame), sizeof(USHORT) );
	wReason = cpu_to_le16( wReason ); //20060926 add by anson's endian
	sSmeMsg.wMsgType = SMEMSG_DEAUTHEN_IND;
	sSmeMsg.wInstance = i;
	sSmeMsg.pMsgPtr = &wReason;
	SME_Entry(Adapter, &sSmeMsg);
	
}

void vMlmeProc_RcvDisAssoc(PWB32_ADAPTER Adapter, pK_MSG psMlmeMsg)
{
	K_MSG	sSmeMsg;
	USHORT		i,wReason;

	i = psMlmeMsg->wInstance;

	wReason	= *(USHORT *)(((psRXDATA)psMlmeMsg->pMsgPtr)->pbFramePtr + sizeof(struct Management_Frame));
	wReason = cpu_to_le16( wReason ); //20060926 add by anson's endian
	sSmeMsg.wMsgType = SMEMSG_DISASSOC_IND;
	sSmeMsg.wInstance = i;
	sSmeMsg.pMsgPtr = &wReason;
	SME_Entry(Adapter, &sSmeMsg);
}

//======================================================================================
//      Action Function of MLME / IBSS State Transition Table 
//======================================================================================
void vMlmeProc_IbssAuthReq(PWB32_ADAPTER Adapter, pK_MSG psMlmeMsg)
{
	USHORT	i;

	i = psMlmeMsg->wInstance;
	psBSS(i)->wAuthSeqNum = 1;

    // if sendauth...() is fail, for Auth-req path,  then send AuthCfm(GIVE_UP) to SME, go JOIN_SYNC
    // for other path, go JOIN_SYNC
	SendAuthenticationRequest(Adapter, i , psSME->bDesiredAuthMode, 1,	MLME_SUCCESS, NULL);
	//--- wait for response
	vMlmeTimerStart(Adapter, i, AUTH_FAIL_TIMEOUT);
	//--- change to next state
	psBSS(i)->wState = IBSS_AUTH_REQ;;
}

void vMlmeProc_IbssRxAuthFrame(PWB32_ADAPTER Adapter, pK_MSG psMlmeMsg)
{
//	K_MSG	sSmeMsg;
	struct	Authentication_Frame_Body	*psAuthFB;
//	UCHAR	bResult;
	USHORT	i;
	USHORT	SeqNo, StatusCode;  //20060926 add by anson's endian

    //---- Specify which BSS !
	i = psMlmeMsg->wInstance;
	
	if (psBSS(i)->bBssType != IBSS_NET) 
		return;
	
	//----- Management Frame Body Address = Frame Ptr + Management MAC Header offset
	psAuthFB = (struct Authentication_Frame_Body *)
					(((psRXDATA)psMlmeMsg->pMsgPtr)->pbFramePtr + sizeof(struct Management_Frame));
        //20060926 add by anson's endian
	SeqNo = cpu_to_le16(psAuthFB->sequenceNumber);
	StatusCode = cpu_to_le16(psAuthFB->statusCode);
        //----end 20060926 add by anson's endian
	//----------- Error/Fail Authenticate Frame Case
	//if  ((psAuthFB->sequenceNumber != 1) || (psAuthFB->statusCode != MLME_SUCCESS)) {	

	if  ((SeqNo != 1) || (StatusCode != MLME_SUCCESS)) {	//20060926 anson's endian
		// Rx any error/fail Authen-frame, don't indicate SME, 
		// just ignore and change next state to IDLE_SCAN
		psBSS(i)->wState = IDLE_SCAN;
		return;
	}
	
    //----- if Rx success AUTH-Frame, save the Authen-Algorithm of rxed AUTH_Frame (peer STA)
    else     
		psBSS(i)->wAuthAlgo = cpu_to_le16( psAuthFB->algorithmNumber ); //20060926 anson's endian

	//-------- Action function -----------------------
	// Send Auth-Frame(2, Change Text / NULL) according to Auth-Algorithem !!!
	// ChallengeTxt must be NULL because HW MAC auto appends ChallengeTxt
	// when algo = SHARE, seqno = 2 && ChallengeTxt = NULL,
/* //It will fail because the callback function is included in SendAuthenticationRequest()
	if (SendAuthenticationRequest(Adapter, i, psAuthFB->algorithmNumber, 
	    ++psAuthFB->sequenceNumber, MLME_SUCCESS, NULL) != -1) {
	    //--- wait for response with correspond to Auth-Frame(2)
	    vMlmeTimerStart(Adapter, i, AUTH_FAIL_TIMEOUT);
	    
	    //------- Change to next state ----------------------
	    if (psBSS(i)->wAuthAlgo == OPEN_AUTH)
	    	psBSS(i)->wState = IBSS_AUTH_IND;
	    else	
	    	psBSS(i)->wState = IBSS_AUTH_CHANLGE;
	}	
	else
	    psBSS(i)->wState = IDLE_SCAN;
*/
	    //------- Change to next state ----------------------
	    if (psBSS(i)->wAuthAlgo == OPEN_AUTH)
	    	psBSS(i)->wState = IBSS_AUTH_IND;
	    else	
	    	psBSS(i)->wState = IBSS_AUTH_CHANLGE;
		SendAuthenticationRequest(Adapter, i, 
                                                    //psAuthFB->algorithmNumber, //20060926 anson's endian
						    //++psAuthFB->sequenceNumber, MLME_SUCCESS, NULL);
                                                    psBSS(i)->wAuthAlgo,
						    SeqNo+1, MLME_SUCCESS, NULL);
	    //vMlmeTimerStart(Adapter, i, AUTH_FAIL_TIMEOUT);
}

void vMlmeProc_IbssRxAuthChallenge(PWB32_ADAPTER Adapter, pK_MSG psMlmeMsg)
{
	struct	Authentication_Frame_Body	*psAuthFB;
	UCHAR	*psChallengeTxt;
	USHORT	i;
	USHORT	SeqNo, StatusCode; //20060926 add by anson's endian

    //---- Specify which BSS !
	i = psMlmeMsg->wInstance;
	
    //---- stop timer with repect to AUTH-Frame(1)
    vMlmeTimerStop(Adapter, i);  
        
	//----- Management Frame Body Address = Frame Ptr + Management MAC Header
	psAuthFB = (struct Authentication_Frame_Body *)
					(((psRXDATA)psMlmeMsg->pMsgPtr)->pbFramePtr + sizeof(struct Management_Frame));
	psChallengeTxt = (UCHAR *)(psAuthFB) + sizeof(struct Authentication_Frame_Body);
        //20060926 add by anson's endian
	SeqNo = cpu_to_le16(psAuthFB->sequenceNumber);
	StatusCode = cpu_to_le16(psAuthFB->statusCode);

	//----------- Error/Fail Authenticate Frame Case
    //--- In Auth-req path, rxed frame is error, send AuthCfm(RETRY), go JOIN_SYNC
	//if  ((psAuthFB->sequenceNumber != 2) || (psAuthFB->statusCode != MLME_SUCCESS))	{ //20060926 anson's endian	
        if  ((SeqNo != 2) || (StatusCode != MLME_SUCCESS))	{
		// free RX frame buffer => It will be free when return to MLMERcvFrame()
		// We send message to confirme SME. 
		vMlmeProc_AuthConfirmSME(Adapter, RETRY);
		psBSS(i)->wState = IDLE_SCAN;
		return;
	}
    // if Rx success AUTH-Frame, save the Authen-Algorithm of rxed AUTH_Frame (peer STA)
    psBSS(i)->wAuthAlgo = cpu_to_le16( psAuthFB->algorithmNumber ); //20060926 anson's endian

	if (psBSS(i)->wAuthAlgo == OPEN_AUTH) {
		// We send message to confirme SME. 
		vMlmeProc_AuthConfirmSME(Adapter, MLME_SUCCESS);
		
       	//------- Change to next state ----------------------
		psBSS(i)->wState = IBSS_STATE_2;
    }		
	else
	{
	    //-------- Action function -----------------------
	    // Send Auth-Frame(3, WEP) according to Auth-Algorithem !!!
	    // if ChallengeTxt != NULL, then SendAuth auto encrypt frame body !
		/*
	    if (SendAuthenticationRequest(Adapter, i, psAuthFB->algorithmNumber, 
	        ++psAuthFB->sequenceNumber, MLME_SUCCESS, (PCHAR) psChallengeTxt) != -1) {
            
	        //--- wait for response with correspond to Auth-Frame(3)
	        vMlmeTimerStart(Adapter, i, AUTH_FAIL_TIMEOUT);
        
        	//------- Change to next state ----------------------
	    	psBSS(i)->wState = IBSS_AUTH_WEP;
	    }
        // if sendauth...() is fail, for Auth-req path,  then send AuthCfm(GIVE_UP) to SME, 
        // go IDLE_SCAN
	    else
		{
		    vMlmeProc_AuthConfirmSME(Adapter, GIVE_UP);
	    	psBSS(i)->wState = IDLE_SCAN;
	    }	
		*/
       	//------- Change to next state ----------------------
    	psBSS(i)->wState = IBSS_AUTH_WEP;
		SendAuthenticationRequest(Adapter, i, 
                                                    //psAuthFB->algorithmNumber,  //20060926 anson's endian
						    //++psAuthFB->sequenceNumber, MLME_SUCCESS,
                                                    psBSS(i)->wAuthAlgo,
							        SeqNo+1, MLME_SUCCESS,
									(PUCHAR) psChallengeTxt);
        vMlmeTimerStart(Adapter, i, AUTH_FAIL_TIMEOUT);
    }	 
}


void vMlmeProc_IbssRxAuthWEP(PWB32_ADAPTER Adapter, pK_MSG psMlmeMsg)
{
	struct	Authentication_Frame_Body	*psAuthFB;
	USHORT	i;
	USHORT	SeqNo, StatusCode, AlgNo;  //20060926 add by anson's endian

	i = psMlmeMsg->wInstance;
	
    //---- stop timer with repect to AUTH-Frame(2)
    vMlmeTimerStop(Adapter, i);  
        
	psAuthFB = (struct Authentication_Frame_Body *)
					(((psRXDATA)psMlmeMsg->pMsgPtr)->pbFramePtr + sizeof(struct Management_Frame));
        //20060926 add by anson's endian
	SeqNo = cpu_to_le16(psAuthFB->sequenceNumber);
	StatusCode = cpu_to_le16(psAuthFB->statusCode);
	AlgNo = cpu_to_le16(psAuthFB->algorithmNumber);
        //--end 20060926 add by anson's endian

	//if  ((psAuthFB->sequenceNumber != 3)|| (psAuthFB->statusCode != MLME_SUCCESS)) {	//20060926 anson's endian
	if  ((SeqNo != 3)|| (StatusCode != MLME_SUCCESS)) {	
		// auth-fail, free RX frame buffer => It will be free at MLMERcvFrame() 
		// Rx any error/fail Authen-frame, don't indicate SME, 
		// just ignore and change next state to IDLE_SCAN
		psBSS(i)->wState = IDLE_SCAN;
		return;
	}
	
	//===================================================================================
    // if compare challenge text is success, then output frame(4, success), go AUTH_IND
    //    else output frame(4, fail), go IDLE_SCAN
    //===================================================================================
	//------- Check "ChallengeText IE && ChallengeText length" 
	if ((*((UCHAR *)psAuthFB + 6) == ELEMENT_ID_CHALLENGE_TEXT) && (*((UCHAR *) psAuthFB + 7) == 128)) {
	    //---- Compare txed ChallengeText with rxed one.
		if (memcmp(psBSS(i)->auth_challengeText, (UCHAR *) psAuthFB + 8, 128) == 0) {	
		    //--- ChallengeText correct
			/*
			if (SendAuthenticationRequest(Adapter, i, psAuthFB->algorithmNumber,++psAuthFB->sequenceNumber,MLME_SUCCESS,NULL) != -1) 
			    psBSS(i)->wState = IBSS_AUTH_IND;
		    else 
			    psBSS(i)->wState = IDLE_SCAN;
			*/
		    psBSS(i)->wState = IBSS_AUTH_IND;
			SendAuthenticationRequest(Adapter, i, //psAuthFB->algorithmNumber,  //20060926 anson's endian
							      //++psAuthFB->sequenceNumber,MLME_SUCCESS,NULL);
                                                              AlgNo,
										SeqNo+1,MLME_SUCCESS,NULL);
			return;
		}
	}
	//-------- Check is fail !
    // if sendauth...() is fail, for Auth-req path,  then send AuthCfm(GIVE_UP) to SME, 
    // go JOIN_SYNC. For other path, go JOIN_SYNC
    SendAuthenticationRequest(Adapter, i, //psAuthFB->algorithmNumber, //20060926 anson's endian
        //++psAuthFB->sequenceNumber,	(USHORT)AUTH_REJECT_REASON_CHALLENGE_FAIL, NULL);
                             AlgNo, 
        						SeqNo+1, (USHORT)AUTH_REJECT_REASON_CHALLENGE_FAIL, NULL);
	psBSS(i)->wState = IDLE_SCAN;
}

void vMlmeProc_IbssRxAuthResult(PWB32_ADAPTER Adapter, pK_MSG psMlmeMsg) 
{
	struct  Authentication_Frame_Body *psAuthFB;
	USHORT	i;

	i = psMlmeMsg->wInstance;
	vMlmeTimerStop(Adapter, i);
	psAuthFB = (struct Authentication_Frame_Body *)
					(((psRXDATA)psMlmeMsg->pMsgPtr)->pbFramePtr + sizeof(struct Management_Frame));
    //---- In Auth-req path, rxed frame is error, send AuthCfm(RETRY), go JOIN_SYNC------
	if  ((cpu_to_le16( psAuthFB->sequenceNumber ) != 4 ||(cpu_to_le16( psAuthFB->statusCode ) != MLME_SUCCESS))) {	//20060926 anson's endian
		vMlmeProc_AuthConfirmSME(Adapter, RETRY);
		psBSS(i)->wState = IDLE_SCAN;
	}
    //---- In AUTH_WEP, rxed frame status = success, send AuthCfm(SUCCESS), go STATE_2 ------
	else {
	    //--- inform SME -------------- 
	    vMlmeProc_AuthConfirmSME(Adapter, MLME_SUCCESS);
	    psBSS(i)->wState = IBSS_STATE_2;
	    
    }
}

void vMlmeProc_IbssDeAuthReq(PWB32_ADAPTER Adapter, pK_MSG psMlmeMsg)
{
	USHORT	i;

	i = psMlmeMsg->wInstance;
	psBSS(i)->wState = INACTIVE;
}

void vMlmeProc_IbssAuthChallengeCallback(PWB32_ADAPTER Adapter, pK_MSG psMlmeMsg)
{
	psMLME_TXCALLBACK psTxCallbackData;
	USHORT	i;

    // Tx Callback, copy HW Challenget text into memory
	i = psMlmeMsg->wInstance;
	psTxCallbackData = psMlmeMsg->pMsgPtr;
	
    //--- Handle success/fail case of AUTH_CALLBACK => fail, go to JOIN_SYNC
	if (psTxCallbackData->bResult == MLME_SUCCESS)
		CardGetChallengeText(Adapter, psBSS(i)->auth_challengeText);
    else		
	    psBSS(i)->wState = IDLE_SCAN;
}

void vMlmeProc_IbssAuthTxComplete(PWB32_ADAPTER Adapter, pK_MSG psMlmeMsg)
{
	psMLME_TXCALLBACK psTxCallbackData;
	USHORT	i;

	i = psMlmeMsg->wInstance;
	psTxCallbackData = psMlmeMsg->pMsgPtr;
	
    //--- Handle success/fail case of AUTH_CALLBACK => fail, go to JOIN_SYNC
	if (psTxCallbackData->bResult == MLME_SUCCESS)
	{
	    //--- indicate SME ----------
        vMlmeProc_AuthIndicateSME(Adapter);
	    psBSS(i)->wState = IBSS_STATE_2;
    }		
    else		
	    psBSS(i)->wState = IDLE_SCAN;
}

void vMlmeProc_IbssAuthFailTimeout(PWB32_ADAPTER Adapter, pK_MSG psMlmeMsg)
{
	USHORT	i;

	//vChkFatalErr(Adapter);
	i = psMlmeMsg->wInstance;

	if (psBSS(i)->wState < IBSS_STATE_2)
	{
		if (psSME->bDesiredAuthMode == SHARE_AUTH)
		{
			psSME->bDesiredAuthMode = OPEN_AUTH;
    		vMlmeProc_AuthConfirmSME(Adapter, RETRY);
		} 
		//----- OPEN-AUTH timeout fail, just GIVE_UP
		else 
    		vMlmeProc_AuthConfirmSME(Adapter, GIVE_UP);
		psBSS(i)->wState = IDLE_SCAN;
	} 
}


